﻿/*
 * Added by laoma 2013-12-16 22:28:05
 * ---------------------------------------------------------------
 * for：added the PersitenceLayer portal interface,
 * all the crud operate work with this interface
 * ---------------------------------------------------------------
 * version:1.0
 * mail:flydragonml@gmail.com
 */
/*
 * Alter by laoxu 1013-12-25 17:00:00
 * ---------------------------------------------------------------
 * for:Added Insert Edit Delete and Query method;
 * ---------------------------------------------------------------
 * mail:lovexurongquan@163.com
 */

using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Linq.Expressions;

namespace HouodeIT.CloudePlatform.IPL
{
    /// <summary>
    /// the portal of Persist Layer to work with sql or nosql 
    /// </summary>
    public interface IPLSession : IUnitWork
    {
        //Exec Sql、Proc and so on
        #region Exec Sql、Proc and so on

        /// <summary>
        /// Ecec the sql without anything returned
        /// </summary>
        /// <param name="strSql">the sql text</param>
        /// <param name="transaction">this is transaction</param>
        /// <param name="param">the parames 4 the sql</param>
        /// <returns>the rows effected</returns>
        int ExecuteNonQuery(string strSql, dynamic param = null, DbTransaction transaction = null);


        /// <summary>
        /// Ecec the sql with one object returned
        /// </summary>
        /// <param name="strSql">the sql text</param>
        /// <param name="param">the parames 4 the sql</param>
        /// <param name="transaction">this is transaction</param>
        /// <returns>the first row and the firt column ,it's the first cell's value</returns>
        T ExecuteScalar<T>(string strSql, dynamic param = null, DbTransaction transaction = null);

        #region Insert

        /// <summary>
        /// insert into database a entity
        /// </summary>
        /// <typeparam name="T">entity type</typeparam>
        /// <param name="entity"> entity value, if strSql is not null,it's param in entity</param>
        /// <param name="strSql">the sql text</param>
        /// <param name="transaction">this is transaction</param>
        /// <returns>the key of commit result</returns>
        int Insert<T>(T entity, string strSql = null, DbTransaction transaction = null);

        /// <summary>
        /// insert into database a entity list
        /// </summary>
        /// <typeparam name="T">entity type</typeparam>
        /// <param name="entityList">entity value list</param>
        /// <param name="strSqlList">the sql text list,if it is not null, the sql must corresponding entityList</param>
        /// <param name="transaction">this is transacation</param>
        /// <returns>the key of commit result</returns>
        List<int> Insert<T>(List<T> entityList, List<string> strSqlList = null, DbTransaction transaction = null);
        #endregion

        #region Edit

        /// <summary>
        /// edit entity by key
        /// </summary>
        /// <typeparam name="T">entity type</typeparam>
        /// <param name="entity">new entity value, if strSql is not null,it's param in entity</param>
        /// <param name="strSql">the sql text</param>
        /// <param name="transaction">this is transacation</param>
        /// <returns>the key of commit result</returns>
        int Edit<T>(T entity, string strSql = null, DbTransaction transaction = null);

        /// <summary>
        /// edit entity list by key
        /// </summary>
        /// <typeparam name="T">entity type</typeparam>
        /// <param name="entityList">the strSql param in new entity value list</param>
        /// <param name="strSqlList">the sql text list, if it is not null, the sql must corresponding entityList</param>
        /// <param name="transaction">this is transacation</param>
        /// <returns>the key of commit result</returns>
        List<int> Edit<T>(List<T> entityList, List<string> strSqlList = null, DbTransaction transaction = null);

        /// <summary>
        /// edit entity by key,T is must be class in model,if you want edit with sql, please assign T, You can pass in a sql str and param for the sql to update one or more entity.
        /// </summary>
        /// <typeparam name="T">entity type</typeparam>
        /// <param name="strSql">the sql text</param>
        /// <param name="param">the param for strSql</param>
        /// <param name="transaction">this is transaction</param>
        /// <returns>the key of commit result</returns>
        int Edit(string strSql, dynamic param = null, DbTransaction transaction = null);

        /// <summary>
        /// edit by lambda, please assign T
        /// </summary>
        /// <typeparam name="T">entity type</typeparam>
        /// <param name="lambdaParam">the sql set value param</param>
        /// <param name="lambdaWhere">the sql where param</param>
        /// <param name="transaction">this transacation</param>
        /// <returns>the key of commit result</returns>
        int Edit<T>(Expression<Func<T>> lambdaParam, Expression<Func<T, bool>> lambdaWhere, DbTransaction transaction = null);
        #endregion

        #region Delete

        /// <summary>
        /// delete by entity key
        /// </summary>
        /// <typeparam name="T">entity type</typeparam>
        /// <param name="entity">entity value, if strSqlis not null, strSql param in entity</param>
        /// <param name="strSql">the sql text</param>
        /// <param name="transaction">this is transacation</param>
        /// <returns>the key of commit result</returns>
        int Delete<T>(T entity, string strSql = null, DbTransaction transaction = null);

        /// <summary>
        /// delete by entity key list
        /// </summary>
        /// <typeparam name="T">entity type</typeparam>
        /// <param name="entityList">entity value list,if strSqlList is not null, the sql must corresponding entityList</param>
        /// <param name="strSqlList">the sql text list</param>
        /// <param name="transaction">this is transacation</param>
        /// <returns>the key of commit result</returns>
        List<int> Delete<T>(List<T> entityList, List<string> strSqlList = null, DbTransaction transaction = null);

        /// <summary>
        /// delete by sql
        /// </summary>
        /// <typeparam name="T">entity type</typeparam>
        /// <param name="strSql">the sql text</param>
        /// <param name="param">the param for strSql</param>
        /// <param name="transaction">this is transacation</param>
        /// <returns>the key of commit result</returns>
        int Delete<T>(string strSql, dynamic param = null, DbTransaction transaction = null);

        /// <summary>
        /// delete by lambda
        /// </summary>
        /// <typeparam name="T">entity type</typeparam>
        /// <param name="lambdaWhere">delete condition</param>
        /// <param name="transaction">this is transacation</param>
        /// <returns>the key of commit result</returns>
        int Delete<T>(Expression<Func<T, bool>> lambdaWhere, DbTransaction transaction = null);
        #endregion

        #region Query

        /// <summary>
        /// query by param
        /// </summary>
        /// <typeparam name="T">entity type, and return this type.</typeparam>
        /// <param name="strSql">the sql text</param>
        /// <param name="param">the param for strSql</param>
        /// <param name="transaction">this is transacation</param>
        /// <returns>A data collection as IEnumerable</returns>
        IEnumerable<T> Query<T>(string strSql, dynamic param = null, DbTransaction transaction = null);

        /// <summary>
        /// query with content entity
        /// </summary>
        /// <typeparam name="TFirst">first entity type</typeparam>
        /// <typeparam name="TSecond">second entity type</typeparam>
        /// <typeparam name="TResult">return entity type</typeparam>
        /// <param name="cb">A callback function to connect the entity instances, or null to automatically guess the relationships</param>
        /// <param name="strSql">the sql text</param>
        /// <param name="param">param for strSql</param>
        /// <param name="transaction">this is trancation</param>
        /// <returns>A data collection as IEnumerable</returns>
        IEnumerable<TResult> Query<TFirst, TSecond, TResult>(Func<TFirst, TSecond, TResult> cb, string strSql, dynamic param = null, DbTransaction transaction = null);

        /// <summary>
        /// query with content entity
        /// </summary>
        /// <typeparam name="TFirst">first entity type</typeparam>
        /// <typeparam name="TSecond">second entity type</typeparam>
        /// <typeparam name="TThird">third entity type</typeparam>
        /// <typeparam name="TResult">return entity type</typeparam>
        /// <param name="cb">A callback function to connect the entity instances, or null to automatically guess the relationships</param>
        /// <param name="strSql">the sql text</param>
        /// <param name="param">param for strSql</param>
        /// <param name="transaction">this is trancation</param>
        /// <returns>A data collection as IEnumerable</returns>
        IEnumerable<TResult> Query<TFirst, TSecond, TThird, TResult>(Func<TFirst, TSecond, TThird, TResult> cb, string strSql, dynamic param = null, DbTransaction transaction = null);

        /// <summary>
        /// query with content entity
        /// </summary>
        /// <typeparam name="TFirst">first entity type</typeparam>
        /// <typeparam name="TSecond">second entity type</typeparam>
        /// <typeparam name="TThird">third entity type</typeparam>
        /// <typeparam name="TFourth">fourth entity type</typeparam>
        /// <typeparam name="TResult">return entity type</typeparam>
        /// <param name="cb">A callback function to connect the entity instances, or null to automatically guess the relationships</param>
        /// <param name="strSql">the sql text</param>
        /// <param name="param">param for strSql</param>
        /// <param name="transaction">this is trancation</param>
        /// <returns>A data collection as IEnumerable</returns>
        IEnumerable<TResult> Query<TFirst, TSecond, TThird, TFourth, TResult>(Func<TFirst, TSecond, TThird, TFourth, TResult> cb, string strSql, dynamic param = null, DbTransaction transaction = null);

        /// <summary>
        /// query page by param
        /// </summary>
        /// <typeparam name="T">entity type, and return this type.</typeparam>
        /// <param name="pageIndex">the current page number</param>
        /// <param name="pageCount">the count in this page</param>
        /// <param name="total">the all count in database</param>
        /// <param name="strSql">the sql text,can be null.</param>
        /// <param name="param">the param in strSql</param>
        /// <param name="transaction">this is transacation</param>
        /// <returns>A data collection as IEnumerable</returns>
        IEnumerable<T> QueryPage<T>(int pageIndex, int pageCount, out long total, string strSql, dynamic param = null, DbTransaction transaction = null);

        /// <summary>
        /// query page with content entity
        /// </summary>
        /// <typeparam name="TFirst">first entity type</typeparam>
        /// <typeparam name="TSecond">second entity type</typeparam>
        /// <typeparam name="TResult">return entity type</typeparam>
        /// <param name="cb">A callback function to connect the entity instances, or null to automatically guess the relationships</param>
        /// <param name="pageIndex">the current page number</param>
        /// <param name="pageCount">the count in this page</param>
        /// <param name="total">the all count in database</param>
        /// <param name="strSql">the sql text</param>
        /// <param name="param">the param in strSql</param>
        /// <param name="transaction">this is transacation</param>
        /// <returns>A data collection as IEnumerable</returns>
        IEnumerable<TResult> QueryPage<TFirst, TSecond, TResult>(int pageIndex, int pageCount, out long total, Func<TFirst, TSecond, TResult> cb, string strSql, dynamic param = null, DbTransaction transaction = null);

        /// <summary>
        /// query page with content entity
        /// </summary>
        /// <typeparam name="TFirst">first entity type</typeparam>
        /// <typeparam name="TSecond">second entity type</typeparam>
        /// <typeparam name="TThird">third entity type</typeparam>
        /// <typeparam name="TResult">return entity type</typeparam>
        /// <param name="cb">A callback function to connect the entity instances, or null to automatically guess the relationships</param>
        /// <param name="pageIndex">the current page number</param>
        /// <param name="pageCount">the count in this page</param>
        /// <param name="total">the all count in database</param>
        /// <param name="strSql">the sql text</param>
        /// <param name="param">the param in strSql</param>
        /// <param name="transaction">this is transacation</param>
        /// <returns>A data collection as IEnumerable</returns>
        IEnumerable<TResult> QueryPage<TFirst, TSecond, TThird, TResult>(int pageIndex, int pageCount, out long total, Func<TFirst, TSecond, TThird, TResult> cb, string strSql, dynamic param = null, DbTransaction transaction = null);

        /// <summary>
        /// query page witn content entity
        /// </summary>
        /// <typeparam name="TFirst">first entity type</typeparam>
        /// <typeparam name="TSecond">second entity type</typeparam>
        /// <typeparam name="TThird">third entity type</typeparam>
        /// <typeparam name="TFourth">fourth entity type</typeparam>
        /// <typeparam name="TResult">return entity type</typeparam>
        /// <param name="cb">A callback function to connect the entity instances, or null to automatically guess the relationships</param>
        /// <param name="pageIndex">the current page number</param>
        /// <param name="pageCount">the count in this page</param>
        /// <param name="total">the all count in database</param>
        /// <param name="strSql">the sql text</param>
        /// <param name="param">the param in strSql</param>
        /// <param name="transaction">this is transacation</param>
        /// <returns>A data collection as IEnumerable</returns>
        IEnumerable<TResult> QueryPage<TFirst, TSecond, TThird, TFourth, TResult>(int pageIndex, int pageCount, out long total, Func<TFirst, TSecond, TThird, TFourth, TResult> cb, string strSql, dynamic param = null, DbTransaction transaction = null);

        #endregion

        #region QueryLambda

        /// <summary>
        /// query by lambda
        /// </summary>
        /// <typeparam name="T">entity type, and return this type.</typeparam>
        /// <param name="lambdaWhere">this is where lambda to query</param>
        /// <param name="transaction">this is transacation</param>
        /// <returns>A data collection as IEnumerable</returns>
        IEnumerable<T> QueryLambda<T>(Expression<Func<T, bool>> lambdaWhere, DbTransaction transaction = null);

        /// <summary>
        /// query page by lambda
        /// </summary>
        /// <typeparam name="T">entity type</typeparam>
        /// <param name="pageIndex">the current page number</param>
        /// <param name="pageCount">the count in this page</param>
        /// <param name="total">the all count in database</param>
        /// <param name="lambdaWhere">this is where lambda to query</param>
        /// <param name="transaction">this is transacation</param>
        /// <returns>A data collection as IEnumerable</returns>
        IEnumerable<T> QueryLambdaPage<T>(int pageIndex, int pageCount, out int total, Expression<Func<T, bool>> lambdaWhere, DbTransaction transaction = null);

        #endregion


        #endregion

    }
}
